package org.eesgmbh.gimv.samples.openstreetmap.client;

import org.eesgmbh.gimv.client.controls.DragImageControl;
import org.eesgmbh.gimv.client.controls.KeystrokeControl;
import org.eesgmbh.gimv.client.controls.MouseWheelControl;
import org.eesgmbh.gimv.client.event.StateChangeEvent;
import org.eesgmbh.gimv.client.presenter.BoundsShiftPresenter;
import org.eesgmbh.gimv.client.presenter.ImagePresenter;
import org.eesgmbh.gimv.client.presenter.OverviewPresenter;
import org.eesgmbh.gimv.client.presenter.ZoomBoxPresenter;
import org.eesgmbh.gimv.client.view.BoundsShiftViewImpl;
import org.eesgmbh.gimv.client.view.GenericWidgetView;
import org.eesgmbh.gimv.client.view.GenericWidgetViewImpl;
import org.eesgmbh.gimv.client.view.ImageViewImpl;
import org.eesgmbh.gimv.shared.util.Bound;
import org.eesgmbh.gimv.shared.util.Direction;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.RootPanel;

public class OpenStreetMapSampleEntryPoint implements EntryPoint {

	public void onModuleLoad() {
		//DeferredCommand is a workaround for GWT-Bug in Java 5, Windows, hosted mode
		//http://code.google.com/p/google-web-toolkit/issues/detail?id=4254
		//Error: java.lang.VerifyError: (class: com/google/gwt/core/client/Scheduler, method: <init> signature: ()V) Illegal constant pool index
		DeferredCommand.addCommand(new Command() {
			public void execute() {
				HandlerManager handlerManager = new HandlerManager(null);
				HandlerManager overviewHandlerManager = new HandlerManager(null);

				OpenStreetMapSampleLayout layout = new OpenStreetMapSampleLayout();

				OpenStreetMapSampleController appController = new OpenStreetMapSampleController(layout.getPrimaryViewport(), layout.getOverviewViewport(), handlerManager, overviewHandlerManager);

				configureGimvComponents(handlerManager, layout);
				configureGimvOverviewComponents(overviewHandlerManager, handlerManager, layout);

				handlerManager.fireEvent(StateChangeEvent.createMove());

				RootPanel.get("rootPanel").add(layout.getRootWidget());

				appController.initApp();
			}
		});
	}

	private void configureGimvComponents(HandlerManager handlerManager, OpenStreetMapSampleLayout layout) {
		ImagePresenter.View imageView = new ImageViewImpl(layout.getChartImage());
		new ImagePresenter(handlerManager, imageView);

		layout.getPrimaryViewport().setHandlerManager(handlerManager);
		layout.getPrimaryViewport().setEnableZoomWhenShiftkeyPressed(true);

		GenericWidgetView zoomBoxView = new GenericWidgetViewImpl(layout.getZoomBox());
		new ZoomBoxPresenter(handlerManager, zoomBoxView);

		new DragImageControl(handlerManager);

		KeystrokeControl keystrokeControl = new KeystrokeControl(handlerManager);
		keystrokeControl.addTargetElement(layout.getPrimaryViewport().getElement());
		keystrokeControl.addTargetElement(layout.getRootWidget().getElement());
		keystrokeControl.addTargetElement(layout.getShiftLeft().getElement());
		keystrokeControl.addTargetElement(layout.getShiftRight().getElement());
		keystrokeControl.addTargetElement(layout.getShiftUp().getElement());
		keystrokeControl.addTargetElement(layout.getShiftDown().getElement());
		keystrokeControl.addDocumentAndBodyAsTarget();

		//offset of 10 pixels on the arrow keys, no modifiers
		keystrokeControl.registerKey(KeyCodes.KEY_LEFT, Direction.EAST, 10);
		keystrokeControl.registerKey(KeyCodes.KEY_UP, Direction.SOUTH, 10);
		keystrokeControl.registerKey(KeyCodes.KEY_RIGHT, Direction.WEST, 10);
		keystrokeControl.registerKey(KeyCodes.KEY_DOWN, Direction.NORTH, 10);

		new MouseWheelControl(handlerManager);

		BoundsShiftPresenter.View shiftLeftView = new BoundsShiftViewImpl(layout.getShiftLeft());
		BoundsShiftPresenter shiftLeftPresenter = new BoundsShiftPresenter(handlerManager, shiftLeftView);
		shiftLeftPresenter.configureProportionalShift(+0.3, 0);

		BoundsShiftPresenter.View shiftRightView = new BoundsShiftViewImpl(layout.getShiftRight());
		BoundsShiftPresenter shiftRightPresenter = new BoundsShiftPresenter(handlerManager, shiftRightView);
		shiftRightPresenter.configureProportionalShift(-0.3, 0);

		BoundsShiftPresenter.View shiftUpView = new BoundsShiftViewImpl(layout.getShiftUp());
		BoundsShiftPresenter shiftUpPresenter = new BoundsShiftPresenter(handlerManager, shiftUpView);
		shiftUpPresenter.configureProportionalShift(0, +0.3);

		BoundsShiftPresenter.View shiftDownView = new BoundsShiftViewImpl(layout.getShiftDown());
		BoundsShiftPresenter shiftDownPresenter = new BoundsShiftPresenter(handlerManager, shiftDownView);
		shiftDownPresenter.configureProportionalShift(0, -0.3);
	}

	private void configureGimvOverviewComponents(HandlerManager overviewHandlerManager,	HandlerManager primaryHandlerManager, OpenStreetMapSampleLayout layout) {
		ImagePresenter.View imageView = new ImageViewImpl(layout.getSmallMap());
		new ImagePresenter(overviewHandlerManager, imageView);

		OverviewPresenter overviewPresenter = new OverviewPresenter(new GenericWidgetViewImpl(layout.getOverview()), overviewHandlerManager, primaryHandlerManager);

		// Specify what widgets handles for dragging are
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getCenterHandle()), Bound.LEFT, Bound.RIGHT, Bound.TOP, Bound.BOTTOM);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getLeftHandle()), Bound.LEFT);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getRightHandle()), Bound.RIGHT);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getTopHandle()), Bound.TOP);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getBottomHandle()), Bound.BOTTOM);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getTopleftHandle()), Bound.TOP, Bound.LEFT);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getToprightHandle()), Bound.TOP, Bound.RIGHT);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getBottomleftHandle()), Bound.BOTTOM, Bound.LEFT);
		overviewPresenter.addHandle(new GenericWidgetViewImpl(layout.getBottomrightHandle()), Bound.BOTTOM, Bound.RIGHT);

		// Dont' let the overview widget get to small
		overviewPresenter.setMinClippingWidth(layout.getMinOverviewWidth());
		overviewPresenter.setMinClippingHeight(layout.getMinOverviewHeight());

		// preserve the aspect ratio of the overview widget
		overviewPresenter.setPreserveAspectRatio(true);

		layout.getOverviewViewport().setHandlerManager(overviewHandlerManager);
	}
}
